// import moduleName=require('../common/moduleName');
import platform = require('../common/baseCommon');
import appClient = require('./appClient');
// import platformControls = require('./controls');

/**
 * 模块名称
 */
export const moduleName = "platform.client";

/** x,y轴类型 */
export type axisType = "value" | "category" | "time" | "log";
/** 位置 */
export type align = "right" | "left" | "center" | "top" | "buttom" | "start" | "end" | "middle" | "inside";
/**图坐标轴边距 */
export type grid = {
    x?: number;
    y?: number;
    x2?: number;
    y2?: number;
};

/** 轴定义 */
export type axis = {
    /** 轴类型 */
    type: axisType,
    /** 轴列表 */
    axises: {
        /** 轴标题 */
        caption?: string,
        /** 轴位置 */
        position?: align,
        /** 轴名称位置 */
        nameLocation?: align,
        /** 倒置 */
        inverse?: boolean,
        /**轴名称角度 */
        nameRotate?: number,
        /**轴名称与轴距离*/
        nameGap?: number,

        color?: string,
        axisLine?: {}

    }[]
};
/** 系列类型 */
export type seriseType = "bar" | "line" | "scatter" | "pie" | "effectScatter" |
    "radar" | "treemap" | "boxplot" | "candlestick" | "heatmap" | "map" | "parallel" |
    "lines" | "graph" | "sankey" | "funnel" | "gauge" | "pictorialBar" | "themeRiver";

/**
 * EChart配置类
 */
@platform.addon('EChart配置类', '用于配置并获取EChart的配置类', moduleName)
export class echartOption extends platform.baseObject {
    option?: any = {};
    /** EChart配置类 */
    constructor() {
        super();
        this.option.tooltip = {};
        this.option.tooltip.trigger = "axis";
        // 坐标轴指示器，坐标轴触发有效
        // 默认为直线，可选为：'line' | 'shadow'
        this.option.tooltip.axisPointer = {
            type: 'shadow'
        };
        this.option.animationEasing = 'elasticOut';
        this.option.animationDelayUpdate = function (idx) {
            return idx * 5;
        };
    }
    /** 设置标题 */
    setText?(text: string) {
        if (!this.option.title) {
            this.option.title = {};
        }
        this.option.title.text = text;
        return this;
    }
    /** 设置副标题 */
    setSubText?(subtext: string) {
        if (!this.option.title) {
            this.option.title = {};
        }
        this.option.title.subtext = subtext;
        return this;
    }
    /** 设置图例位置 */
    setLegendPosition?(x?: align, y?: align) {
        const defaultx = "center", defaulty = "top";
        if (!this.option.legend)
            this.option.legend = {};
        this.option.legend.x = x ? x : defaultx;
        this.option.legend.y = y ? y : defaulty;
        return this;
    }
    /**
     * 设置图例摆放方向
     * @param orient 摆放方向(横排还是竖排)
     */
    setLegendOrient(orient: string) {
        if (!this.option.legend)
            this.option.legend = {};
        this.option.legend.orient = orient;

    }

    /** 设置图例数据 */
    setLegend?(data: any) {
        if (!this.option.legend.data) {
            this.option.legend.data = [];
        }
        this.option.legend.data.push({ name: data });
        return this;
    }
    /** 设置图边距 */
    setGrid?(g: grid) {
        if (!this.option.grid)
            this.option.grid = {};
        this.option.grid = g;
    }

    /** 设置x轴 */
    setxAxis?(x: any, italic: boolean = false) {
        if (italic) {
            for (let index = 0; index < x.length; index++) {
                let element = x[index];
                element.axisTick = {};
                element.axisTick.alignWithLabel = true;
                element.axisLabel = {};
                element.axisLabel.interval = 0;
                element.axisLabel.rotate = -35;

            }
        }
        this.option.xAxis = x;
        return this;
    }
    /** 设置y轴 */
    setyAxis?(y: any) {
        this.option.yAxis = y;
        return this;
    }
    /** 设置种类轴数据
     * @description 每个种类轴的数据是不能重复的
     */
    setCategoryAxisValue?(value: any, index: number) {
        if (this.option.xAxis && this.option.xAxis[0].type == "category") {
            if (this.option.xAxis[index].data.indexOf(value) == -1) {
                this.option.xAxis[index].data.push(value);
            }
            return this;
        }
        if (this.option.yAxis && this.option.yAxis[0].type == "category") {
            if (this.option.yAxis[index].data.indexOf(value) == -1) {
                this.option.yAxis[index].data.push(value);
            }
            return this;
        }
    }
    /** 设置系列 */
    setSerie?(serie: any) {
        if (!this.option.series) {
            this.option.series = [];
        }
        serie.animationDelay = function (idx) {
            return idx * 10 + 100;
        };
        this.option.series.push(serie);
        return this;
    }
    /**
     * 设置系统名称
     * @param name 设置名称
     * @param index 系列序号
     */
    setSerieName(name: string, index: number) {
        this.option.series[index].name = name;
    }
    /** 设置系列数据 */
    setSerieValue?(value: any, index: number) {
        this.option.series[index].data.push(value);
        return this;
    }
    setDataEmpty?() {
        if (this.option.series) {
            for (let index = 0, len = this.option.series.length;
                index < len; index++) {
                this.option.series[index].data = []
            }
        }
        if (this.option.xAxis && this.option.xAxis[0].type == "category") {
            for (let index = 0, len = this.option.xAxis.length;
                index < len; index++) {
                this.option.xAxis[index].data = [];
            }
        }
        if (this.option.yAxis && this.option.yAxis[0].type == "category") {
            for (let index = 0, len = this.option.yAxis.length;
                index < len; index++) {
                this.option.yAxis[index].data = [];
            }
        }
        return this;
    }
    /** 获取配置 */
    getOption?() {
        return this.option;
    }
}

/**
 * 系列配置
 * @author huyl
 */
@platform.addon('系列配置', 'EChart对应每个系列的配置', moduleName)
export class serieObject extends platform.baseObject {
    /** 配置 */
    options?: echartOption;
    /**图例显示 */
    legend?: boolean;
    /** 图例位置配置 */
    legendPosition?: { x?: align, y?: align };
    /** 坐标轴边距 */
    currentGrid?: grid;
    /**
     * 当前配置
     * @description 用于getOption时重复生成optionthis.currentOption
     */
    protected currentOption?: any = undefined;
    /** 系列配置 */
    constructor() {
        super();
        this.options = new echartOption();
    }
    /** 获取配置 */
    getOption?(): any {
        if (this.currentOption) {
            return this.currentOption;
        }
        if (this.legend) {
            if (this.legendPosition) {
                this.options.setLegendPosition(
                    this.legendPosition.x,
                    this.legendPosition.y
                );
            } else {
                //debugger;
                this.options.setLegendPosition();
            }
        }

        if (this.currentGrid) {
            this.options.setGrid(this.currentGrid);
        }
        if (this.onGetOption) {
            this.currentOption = this.onGetOption();
        } else {
            this.currentOption = this.options.getOption();
        }
        return this.currentOption;
    }
    /** 显示 */
    show?(data: platform.dataTable): any {
        if (data && data.rows.length < 0) {
            return this.getOption();
        }
        return this.onShow(data);
    }
    /** 显示事件 */
    onShow?(data: platform.dataTable): any { }
    /** 获取配置事件 */
    onGetOption?(): any { }
}

/**
 * 轴系列图
 */
@platform.addon('轴系列图', 'EChart系列中折线图,饼图的抽象', moduleName)
export class axisSerie extends serieObject {
    /** 
     * 种类字段列表 
     * @description 对应种类类型的轴的数据来源字段,以及对应的轴的序号
     * */
    categoryFields?: { field: platform.dataField, index: number }[];
    /** 
     * 值字段列表 
     * @description 对应值类型的轴的数据来源字段,以及对应的x,y轴的序号
     * */
    valueFields?: {
        type: seriseType,
        field: platform.dataField,
        xAxisIndex: number,
        yAxisIndex: number,
        barMaxWitdh?: number,//柱体最大宽度
        itemStyle?: {
            normal?: {
                color?: string,//柱体颜色
            }
        },

    }[];
    /** x轴 */
    xAxis?: axis;
    /** y轴 */
    yAxis?: axis;
    /** x轴标题是否斜体 */
    italic?: boolean = false;

    //barMaxWitdh?:number;
    /** 轴系列图 */
    constructor() {
        super();
    }
    onGetOption?() {
        // 设置x,y轴
        if (this.xAxis && this.yAxis) {
            let x = this.initAxis(this.xAxis);
            let y = this.initAxis(this.yAxis);
            this.options
                .setxAxis(x, this.italic)
                .setyAxis(y);
        }
        // 添加系列并添加图例数据
        for (let index = 0, len = this.valueFields.length;
            index < len; index++) {
            let serie = {};
            let serieConfig = this.valueFields[index];
            serie['name'] = serieConfig.field.caption;
            serie['type'] = serieConfig.type;
            serie['data'] = [];
            serie['yAxisIndex'] = serieConfig.yAxisIndex;
            serie['xAxisIndex'] = serieConfig.xAxisIndex;

            if (serieConfig.type == 'bar') {
                serie['barMaxWidth'] = serieConfig.barMaxWitdh;
                serie['itemStyle'] = serieConfig.itemStyle;
            }

            if (this.legend) {
                this.options.setLegend(serie['name']);
            }
            this.options.setSerie(serie);
        }
        return this.options.getOption();
    }
    onShow?(data: platform.dataTable) {
        this.options.setDataEmpty();
        data.rows.forEach((row: platform.dataRow, index: number) => {
            let rowValue = row.rowValues;
            // 添加种类数据
            for (let index = 0, len = this.categoryFields.length;
                index < len; index++) {
                let category = this.categoryFields[index];
                let categoryValue = rowValue[category.field.name];
                if (categoryValue)
                    this.options.setCategoryAxisValue(categoryValue, category.index)
            }
            // 添加系列的数据
            for (let index = 0, len = this.valueFields.length;
                index < len; index++) {
                let valueField = this.valueFields[index].field;
                if (rowValue[valueField.name])
                    this.options.setSerieValue(rowValue[valueField.name], index);
            }
        });
        return this.options.getOption();
    }
    /** 初始化轴 */
    private initAxis?(axisConfig: axis) {
        let retAxis = [];
        let retType = axisConfig.type;
        for (let index = 0, len = axisConfig.axises.length;
            index < len; index++) {
            let item = axisConfig.axises[index];
            // 倒置
            let inverse = item.inverse;
            let tempAxis = {};
            if (inverse) {
                tempAxis = {
                    type: retType,
                    name: item.caption,
                    inverse: inverse,
                    splitLine: {
                        show: false
                    }
                };
            } else {
                tempAxis = {
                    type: retType,
                    name: item.caption,
                    splitLine: {
                        show: false
                    }
                };
            }
            if (item.position) tempAxis["position"] = item.position;
            if (item.nameLocation) tempAxis["nameLocation"] = item.nameLocation;
            if (item.nameGap) tempAxis["nameGap"] = item.nameGap;
            if (item.nameRotate) tempAxis["nameRotate"] = item.nameRotate;
            let axisLineStyle = {};
            if (item.color) axisLineStyle["color"] = item.color;
            tempAxis["axisLine"] = {
                lineStyle: axisLineStyle
            };

            retAxis.push(tempAxis);
        }
        return retAxis;
    }
}

/**
 * 饼图系列图
 */
@platform.addon('饼图', '描述', moduleName)
export class pieSerie extends serieObject {
    /**
     * 饼图个数最多4个
     */
    pieNumber?: number = 1;
    /**
     * 饼图半径
     */
    radius?: string;
    center?: string;
    /**
     * 标题（位置为顶置中心）
     */
    pieTitle?: string;

    /**
     * 种类字段名
     */
    fieldTypeName?: string;

    /**
     * 数据字段名
     */
    fieldData: platform.dataField[];


    constructor() {
        super();
    }

    onGetOption?() {
        //创建标题
        this.options.setText(this.pieTitle);
        this.options.setLegendPosition('left');
        //创建Legend
        let legend = {};
        for (let key of this.fieldData) {
            this.options.setLegend(key.caption);
        }
        //let serie = undefined;
        //构造饼图
        if (this.pieNumber == 1) {
            this.buildOnePie();
        }
        if (this.pieNumber == 2) {
            this.buildTwoPie();
        }
        if (this.pieNumber == 3) {
            this.buildThreePie();
        }
        if (this.pieNumber >= 4) {
            this.buildFourPie();
        }
        //this.options.setSerie(serie);
        return this.options.getOption();
    }
    onShow?(data: platform.dataTable): any {
        this.options.setDataEmpty();
        this.options.setLegendOrient('vertical');
        //遍历行数据
        for (var i = 0; i < data.rows.length; i++) {
            let value = data.rows[i].rowValues;
            if (i >= this.pieNumber)
                break;
            //设置标题
            this.options.option.title[i].text = value[this.fieldTypeName];
            //遍历所有字段信息
            for (let key of this.fieldData) {
                //饼图数据赋值
                let itemdata = {};
                itemdata['name'] = key.caption;
                itemdata['value'] = value[key.name];
                this.options.setSerieValue(itemdata, i);
            }
        }
        return this.options.getOption();
    }
    /**
     * 创建一个饼图
     */
    private buildOnePie?() {
        let serie = {};
        serie['name'] = '';
        serie['type'] = 'pie';
        serie['data'] = [];
        this.options.setSerie(serie);
        //创建饼图标题
        let title = {};
        title['text'] = '';
        title['x'] = '50%';
        title['y'] = 'bottom';
        title['textAlign'] = 'center';
        this.options.option.title = [];
        this.options.option.title.push(title);
    }
    /**
     * 创建两个个饼图
     */
    private buildTwoPie() {
        let serieList = [];
        let titlelist = [];
        if (this.options.option.title)
            this.options.option.title = [];
        for (var i = 0; i < 2; i++) {
            let serieItem = {};
            serieItem['name'] = '';
            serieItem['type'] = 'pie';
            serieItem['radius'] = '50%';
            serieItem['center'] = [];
            serieItem['data'] = [];
            this.options.setSerie(serieItem);
            serieList.push(serieItem);
            //创建标题
            let titleItem = {};
            titleItem['text'] = '';
            titleItem['x'] = '';
            titleItem['y'] = 'bottom';
            titleItem['textAlign'] = 'center';
            this.options.option.title.push(titleItem);
            titlelist.push(titleItem);
        }
        serieList[0].center = ['25%', '50%'];
        this.options.option.title[0].x = '25%';
        serieList[1].center = ['75%', '50%'];
        this.options.option.title[1].x = '75%';
        return serieList;
    }
    /**
     * 创建三个饼图
     */
    private buildThreePie() {
        let serieList = [];
        let titlelist = [];
        if (this.options.option.title)
            this.options.option.title = [];
        for (var i = 0; i < 3; i++) {
            let serieItem = {};
            serieItem['name'] = '';
            serieItem['type'] = 'pie';
            serieItem['radius'] = '30%';
            serieItem['center'] = [];
            serieItem['data'] = [];
            this.options.setSerie(serieItem);
            serieList.push(serieItem);

            //创建标题
            let titleItem = {};
            titleItem['text'] = '';
            titleItem['x'] = '';
            titleItem['y'] = 'bottom';
            titleItem['textAlign'] = 'center';
            this.options.option.title.push(titleItem);
            titlelist.push(titleItem);
        }
        serieList[0].center = ['20%', '50%'];
        this.options.option.title[0].x = '20%';
        serieList[1].center = ['50%', '50%'];
        this.options.option.title[1].x = '50%';
        serieList[2].center = ['80%', '50%'];
        this.options.option.title[2].x = '80%';
        return serieList;
    }

    /**
    * 创建四个饼图
    */
    private buildFourPie() {
        let serieList = [];
        let titlelist = [];
        if (this.options.option.title)
            this.options.option.title = [];
        for (var i = 0; i < 4; i++) {
            let serieItem = {};
            serieItem['name'] = '';
            serieItem['type'] = 'pie';
            serieItem['radius'] = '35%';
            serieItem['center'] = [];
            serieItem['data'] = [];
            this.options.setSerie(serieItem);
            serieList.push(serieItem);
            //创建标题
            let titleItem = {};
            titleItem['text'] = '';
            titleItem['x'] = '';
            titleItem['y'] = '';
            titleItem['textAlign'] = 'center';
            this.options.option.title.push(titleItem);
            titlelist.push(titleItem);
        }
        serieList[0].center = ['25%', '25%'];
        this.options.option.title[0].x = '25%';
        this.options.option.title[0].y = '45%';
        serieList[1].center = ['75%', '25%'];
        this.options.option.title[1].x = '75%';
        this.options.option.title[1].y = '45%';
        serieList[2].center = ['25%', '75%'];
        this.options.option.title[2].x = '25%';
        this.options.option.title[2].y = 'bottom';
        serieList[3].center = ['75%', '75%'];
        this.options.option.title[3].x = '75%';
        this.options.option.title[3].y = 'bottom';
        return serieList;
    }
}

/**
 * 行饼图系列图
 */
@platform.addon('行饼图', '每一行数据是饼图的一个区域的饼图', moduleName)
export class rowPieSerie extends serieObject {

    /** 系列标题 */
    serieCaption?: string;

    /** 种类字段 */
    categoryField?: { field: platform.dataField }

    /** 值字段 */
    valueField?: { field: platform.dataField }

    /** 是否显示点标记的线 */
    isShowLabelLine?: boolean = true;

    /** 点标记文字颜色字符串 */
    labelColor?: string;

    /** 点标记字体大小 */
    labelFontSize?: number;

    /**饼图开始角度 */
    startAngle?: number;
    /** 
     * 点标记显示的格式字符串
     * @description 默认用{b}：{c} ({d}%)，即类型名：数值（百分比）
     */
    labelFormatter?: string = '{b}：{d}%'

    /**
     * 提示模板格式字符串
     * @description 默认用{a} <br/>{b} : {c} ({d}%)，即
     * 系列名
     * 类型名：数值（百分比）
     */
    tooltipFormatter?: string = '{a} <br/>{b} : {c} ({d}%)'

    onGetOption?() {
        debugger;
        // 添加系列并添加图例数据
        let serie = {};
        let labelNormalTextStyle = {};
        if (this.labelColor) {
            labelNormalTextStyle['color'] = this.labelColor;
        }
        if (this.labelFontSize && this.labelFontSize > 0) {
            labelNormalTextStyle['fontSize'] = this.labelFontSize;
        }

        serie['name'] = this.serieCaption ? this.serieCaption : this.categoryField.field.caption;
        serie['type'] = "pie";
        serie['radius'] = '30%';
        serie['data'] = [];
        serie['label'] = {
            normal: {
                textStyle: labelNormalTextStyle,
                formatter: this.labelFormatter
            }
        };
        if (this.startAngle) { serie['startAngle'] = this.startAngle; }
        serie['labelLine'] = {
            normal: {
                show: this.isShowLabelLine
            }
        };
        //this.options.setLegend(serie['name']);
        this.options.setSerie(serie);
        let option = this.options.getOption();
        option['tooltip'] = {
            trigger: 'item',
            formatter: this.tooltipFormatter
        }
        return option;
    }

    onShow?(data: platform.dataTable) {
        debugger;
        this.options.setDataEmpty();
        data.rows.forEach((row: platform.dataRow, index: number) => {
            let rowValue = row.rowValues;
            // 添加图例
            let categoryValue = rowValue[this.categoryField.field.name];
            if (this.legend) {
                if (categoryValue) {
                    this.options.setLegend(categoryValue);
                }
            }

            // 添加系列的数据
            let value = rowValue[this.valueField.field.name];
            if (categoryValue && value) {
                let data = {
                    value: value,
                    name: categoryValue
                }
                this.options.setSerieValue(data, 0);
            }
        });
        debugger;
        return this.options.getOption();
    }
}
